<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet  version="2.0"
	xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
	xmlns:xsd="http://www.w3.org/2001/XMLSchema"
	xmlns:ccts="urn:un:unece:uncefact:documentation:standard:CoreComponentsTechnicalSpecification:2">
	
	<xsl:import href="GlobalVars.xsl"/>
	
	<xsl:template name="GetAnnotatedValue">
		<xsl:param name="element.den" />
		
		<xsl:value-of select="document( $global.file.annotations )/annotations/core-component[
			@den = $element.den]/default-value" />
	</xsl:template>
	
	<!-- 
		Returns all child element for parent and there position if it is defined in the annotations file.
		Otherwise the position will be 99999 so that they wil come after the the elements that have
		an position defined in the annotations file.
		@parent 			- 	The parent element from which to get the children.
		@parent.schema 	- 	The schema in which the element is declared. This can be ommitted when
								the element is in the rootschema.
	-->
	<xsl:template name="GetChildElements">
		<xsl:param name="parent" />
		<xsl:param name="parent.schema" />
		
		<xsl:variable name="complexType" select="if( $parent.schema = '') 
			then document( $global.schema.root )//xsd:complexType[@name = $parent ]
			else document( $parent.schema )//xsd:complexType[@name = $parent ]"/>
		
		<xsl:for-each select="$complexType/xsd:sequence/xsd:element">
			<xsl:variable name="den" select="xsd:annotation/xsd:documentation/ccts:DictionaryEntryName" />
			<xsl:copy>
				<xsl:copy-of select="@*" />
				<xsl:copy-of select="*" />
				<xsl:choose>
					<xsl:when test="document( '../annotations/annotations.xml' )/annotations/core-component[
						@den = $den]/position">
						<xsl:copy-of
							select="document( '../annotations/annotations.xml' )/annotations/core-component[
							@den = $den]/position" />
					</xsl:when>
					<xsl:otherwise>
						<xsl:element name="position">99999</xsl:element>
					</xsl:otherwise>
				</xsl:choose>
			</xsl:copy>
		</xsl:for-each>
	</xsl:template>
	
	<!--
		Returns the document in which the datatype is defined.
		@element.type - The element type for which the schema is looked up.
		@element.schema- The document in which the datatype is used (not defined).
		
		Note I: This template isn't very advanced at the moment. It asumes that the document in which
		the dataType is used also imports the document where the datatype is declared.
		
		Note II: The dataType variable must contain the namespace prefix of the namespace in 
		which the datatype is declared.
	-->
	<xsl:template name="GetDataTypeDocument">
		<xsl:param name="element.type" />
		<xsl:param name="element.schema" />
			
		<xsl:variable name="element.type.prefix" select="substring-before( $element.type, ':' )" />
		
		<xsl:variable name="element.type.ns" 
			select="if( $element.schema = '' ) 
			then document( $global.schema.root )/xsd:schema/namespace::*
				[name() = $element.type.prefix ]
			else document( $element.schema )/xsd:schema/namespace::*
				[name() = $element.type.prefix ]"/>
		
		<xsl:variable name="element.schema.ns" select="if( $element.schema = '' ) 
			then document( $global.schema.root )/xsd:schema/@targetNamespace
			else document( $element.schema )/xsd:schema/@targetNamespace"/>
		
		<xsl:choose>
			<xsl:when test="$element.schema.ns != $element.type.ns">
				<xsl:variable name="element.type.schema" select="if( $element.schema = '' )
					then document( $global.schema.root )/xsd:schema/xsd:import[
						@namespace = $element.type.ns]/@schemaLocation
					else document( $element.schema )/xsd:schema/xsd:import[
						@namespace = $element.type.ns]/@schemaLocation"/>
				<xsl:value-of select="document-uri( document( $element.type.schema ) )" />
			</xsl:when>
			<xsl:otherwise>
				<xsl:value-of select="$element.schema" />
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>
	
	<!-- 
		Returns the name of the type on which element.type is based.
	-->
	<xsl:template name="GetBaseType">
		<xsl:param name="element.type" />
		<xsl:param name="element.type.schema" />
		
		<xsl:if test="if( not( contains( $element.type, ':') ) )
			then error( QName( 'E', 'E' ), concat( 'global-templates.xsl 
			: GetBaseType : element.type must contain a prefix 
			- value = ', $element.type ) )
			else true()" />
		
		<xsl:variable name="type" select="substring-after( $element.type, ':' )" />
		
		<xsl:variable name="element.type.def" select="if( $element.type.schema = '' ) 
			then document( $global.schema.root )/xsd:schema/xsd:complexType[@name = $type]
			else document( $element.type.schema )/xsd:schema/xsd:complexType[ @name = $type ]"/>
		
		<xsl:value-of select="$element.type.def/xsd:simpleContent/xsd:restriction/@base" />
	</xsl:template>
	
	<xsl:template name="GetContentType">
		<xsl:param name="element.type" />
		<xsl:param name="element.type.schema" />
		
		<xsl:variable name="element.type.simple">
			<xsl:call-template name="BasedOnSimpleType">
				<xsl:with-param name="element.type" select="$element.type" />
				<xsl:with-param name="element.type.schema" select="$element.type.schema" />
			</xsl:call-template>
		</xsl:variable>
		
		<xsl:choose>
			<xsl:when test="$element.type.simple = false()">
				<xsl:if test="if( true() )then error( QName( 'E', 'E' ), concat( 'global-templates.xsl 
					: GetContentType : element.type must be based on a SimpleType. element.type = ', $element.type ) )
					else true()" />
			</xsl:when>
			<xsl:otherwise>
				<xsl:variable name="type" select="substring-after( $element.type, ':' )" />
				
				<xsl:variable name="element.type.def" select="if( $element.type.schema = '' ) 
					then document( $global.schema.root )/xsd:schema/xsd:simpleType[@name = $type]
					else document( $element.type.schema )/xsd:schema/xsd:simpleType[ @name = $type ]"/>
				
				<xsl:value-of select="$element.type.def/xsd:restriction/@base" />
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>
	
	<!-- 
		This templates walks the inherance tree up from the given type to the unqualified type and
		returns the first type found which contains a type defeniftion for the given attribute.
		
		Returns in the form:
		<basetype name="{basetype}" schema="{basetype-schema" />
	-->
	<xsl:template name="GetBaseTypeWithAttribute">
		<xsl:param name="type"/>
		<xsl:param name="type.attribute" />
		<xsl:param name="type.schema" />
		
		<!-- 
			Get the basetype.
		-->
		<xsl:variable name="type.basetype">
			<xsl:call-template name="GetBaseType">
				<xsl:with-param name="element.type" select="$type"/>
				<xsl:with-param name="element.type.schema" select="$type.schema" />
			</xsl:call-template>
		</xsl:variable>
		
		<xsl:variable name="type.basetype.schema">
			<xsl:call-template name="GetDataTypeDocument">
				<xsl:with-param name="element.type" select="$type.basetype"/>
				<xsl:with-param name="element.schema" select="$type.schema"/>
			</xsl:call-template>
		</xsl:variable>
		
		<!-- 
			Try to get the type of the attribute.
		-->
		
		<xsl:variable name="type.basetype.attribute.type" 
			select="document( $type.basetype.schema )/xsd:schema/xsd:complexType
			[@name = substring-after( $type.basetype, ':' )]/xsd:simpleContent//xsd:attribute
			[@name = $type.attribute]/@type" />
		
		<xsl:choose>
			<xsl:when test="$type.basetype.attribute.type">
				<xsl:element name="basetype">
					<xsl:attribute name="name" select="$type.basetype" />
					<xsl:attribute name="schema" select="$type.basetype.schema" />
				</xsl:element>
				
			</xsl:when>
			<xsl:otherwise>
				<!--
					If type.basetype is not an unqualified datatype and doesn't contain a type
					declaration for the given attribute, walk up the three one step and give it
					another shot.
					Otherwhise the attribute doesn't seem to be declared for the datatype. It's
					like looking for a languageCode in AmountType.
				-->
				<xsl:if test="not( contains( $global.datatypes.unqualified, $type.basetype ) )">
					<xsl:call-template name="GetBaseTypeWithAttribute">
						<xsl:with-param name="type" select="$type.basetype" />
						<xsl:with-param name="type.schema" select="$type.basetype.schema" />
						<xsl:with-param name="type.attribute" select="$type.attribute" />
					</xsl:call-template>
				</xsl:if>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>
	
	<!-- 
		Looks for the unqualfied datatype on which this qualified datatype is based.
		
		@element.type - The type for which to look up the UnqualifiedDataType.
		@element.type.schema - The document in which the QualifiedDataType is defined or empty 
		if it's defined in the rootschema.
	-->
	<xsl:template name="GetUnqualifiedDataType">
		<xsl:param name="element.type" />
		<xsl:param name="element.type.schema" />
		
		<xsl:if test="if( not( contains( $element.type, ':') ) )
			then error( QName( 'E', 'E' ), concat( 'global-templates.xsl : GetUnqualifiedDataType : element.type must contain a prefix - value = ', $element.type ) )
			else true()" />
		
		<xsl:variable name="element.type.base" >
			<xsl:call-template name="GetBaseType">
				<xsl:with-param name="element.type" select="$element.type" />
				<xsl:with-param name="element.type.schema" select="$element.type.schema" />
			</xsl:call-template>
		</xsl:variable>
		
		<xsl:choose>
			<!--	First case:  element.type is itself an unqualified data type. -->
			<xsl:when test="contains( $global.datatypes.unqualified, substring-after( $element.type, ':' ) )">
				<xsl:value-of select="$element.type" />
			</xsl:when>
			<!--
				Second case:  element.type is an qualified Code Type or ID Type which is directly based on some
				content type in stead of on an other qualified data type or an unqualified datatype. 
			-->
			<xsl:when test="$element.type.base  = ''  ">
				<!--
					Here the basetype is probably a CodeType or an IDType. The qualified datatype is directly based
					on a content type.
				-->
				<xsl:variable name="element.den" select="if( $element.type.schema = '' )
					then document( $global.schema.root )/xsd:schema/xsd:simpleType[@name = substring-after( $element.type, ':' )]/xsd:annotation/xsd:documentation/ccts:DictionaryEntryName
					else document( $element.type.schema )/xsd:schema/xsd:simpleType[@name = substring-after( $element.type, ':' )]/xsd:annotation/xsd:documentation/ccts:DictionaryEntryName"/>
				
				<xsl:choose>
					<xsl:when test="contains( $element.den, 'Code. Type' )">
						<xsl:value-of>udt:CodeType</xsl:value-of>
					</xsl:when>
					<xsl:when test="contains( $element.den, 'ID. Type' )">
						<xsl:value-of>udt:IDType</xsl:value-of>
					</xsl:when>
					<xsl:otherwise>
						<xsl:if test="if( true() ) 
						then 
							error( QName( 'E', 'E' ), concat( 'Found an element for which the base type is not directly  an unqualified or an qualified data type. This is probably an Code Type or an ID Type which is directly based on some content type. Check if the dictionary entry name of this element is correct. element.den: ', $element.type)  ) 
						else 
							true()" />
					</xsl:otherwise>
				</xsl:choose>
			</xsl:when>
			<!--
				NOTE: This test can be changed to be more generic. The test should be:
				
				substring-before( $element.type.base, ':'  ) = 'udt'
				
				Because according to the spec each unqualified datatype should be in a namespace named udt.
				see section 7.6.3 of the XML NDS.
			-->
			<!-- 	Third case: element.type is a qualified data type which is based on an unqualified  data type. 	-->
			<xsl:when test="contains( $global.datatypes.unqualified, substring-after( $element.type.base, ':' ) )">
				<xsl:value-of select="$element.type.base" />
			</xsl:when>
			<!-- 	Fourth case: element.type is a qualified data type which is based on an qualified  data type. -->
			<xsl:otherwise>
				<xsl:variable name="element.basetype.schema">
					<xsl:call-template name="GetDataTypeDocument">
						<xsl:with-param name="element.type" select="$element.type.base" />
						<xsl:with-param name="element.schema" select="$element.type.schema" />						
					</xsl:call-template>
				</xsl:variable>
				<xsl:call-template name="GetUnqualifiedDataType">
					<xsl:with-param name="element.type" select="$element.type.base"/>
					<xsl:with-param name="element.type.schema" select="$element.basetype.schema"/>
				</xsl:call-template>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>
	
	<xsl:template name="BasedOnSimpleType">
		<xsl:param name="element.type" />
		<xsl:param name="element.type.schema" />
		
		<xsl:if test="if( not( contains( $element.type, ':') ) )
			then error( QName( 'E', 'E' ), concat( 'global-templates.xsl : GetUnqualifiedDataType : element.type must contain a prefix - value = ', $element.type ) )
			else true()" />
		
		<xsl:variable name="element.type.base" >
			<xsl:call-template name="GetBaseType">
				<xsl:with-param name="element.type" select="$element.type" />
				<xsl:with-param name="element.type.schema" select="$element.type.schema" />
			</xsl:call-template>
		</xsl:variable>
		
		<xsl:choose>
			<!--	First case:  element.type is itself an unqualified data type. -->
			<xsl:when test="contains( $global.datatypes.unqualified, substring-after( $element.type, ':' ) )">
				<xsl:value-of select="false()" />
			</xsl:when>
			<!--
				Second case:  element.type is an qualified Code Type or ID Type which is directly based on some
				content type in stead of on an other qualified data type or an unqualified datatype. 
			-->
			<xsl:when test="$element.type.base  = ''  ">
				<!--
					Here the basetype is probably a CodeType or an IDType. The qualified datatype is directly based
					on a content type.
				-->
				<xsl:variable name="element.den" select="if( $element.type.schema = '' )
					then document( $global.schema.root )/xsd:schema/xsd:simpleType[@name = substring-after( $element.type, ':' )]/xsd:annotation/xsd:documentation/ccts:DictionaryEntryName
					else document( $element.type.schema )/xsd:schema/xsd:simpleType[@name = substring-after( $element.type, ':' )]/xsd:annotation/xsd:documentation/ccts:DictionaryEntryName"/>
				
				<xsl:choose>
					<xsl:when test="contains( $element.den, 'Code. Type' )">
						<xsl:value-of select="true()"/>
					</xsl:when>
					<xsl:otherwise>
						<xsl:if test="if( true() ) 
							then 
							error( QName( 'E', 'E' ), concat( 'Found an element for which the base type is not directly  an unqualified or an qualified data type. This is probably an Code Type or an ID Type which is directly based on some content type. Check if the dictionary entry name of this element is correct. element.den: ', $element.type)  ) 
							else 
							true()" />
					</xsl:otherwise>
				</xsl:choose>
			</xsl:when>
			<!--
				NOTE: This test can be changed to be more generic. The test should be:
				
				substring-before( $element.type.base, ':'  ) = 'udt'
				
				Because according to the spec each unqualified datatype should be in a namespace named udt.
				see section 7.6.3 of the XML NDS.
			-->
			<!-- 	Third case: element.type is a qualified data type which is based on an unqualified  data type. 	-->
			<xsl:when test="contains( $global.datatypes.unqualified, substring-after( $element.type.base, ':' ) )">
				<xsl:value-of select="false()" />
			</xsl:when>
			<!-- 	Fourth case: element.type is a qualified data type which is based on an qualified  data type. -->
			<xsl:otherwise>
				<xsl:variable name="element.basetype.schema">
					<xsl:call-template name="GetDataTypeDocument">
						<xsl:with-param name="element.type" select="$element.type.base" />
						<xsl:with-param name="element.schema" select="$element.type.schema" />						
					</xsl:call-template>
				</xsl:variable>
				<xsl:call-template name="BasedOnSimpleType">
					<xsl:with-param name="element.type" select="$element.type.base"/>
					<xsl:with-param name="element.type.schema" select="$element.basetype.schema"/>
				</xsl:call-template>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>
	
	<xsl:template name="GetAttributeInfo">
		<xsl:param name="type" />
		<xsl:param name="type.schema" />
		<xsl:param name="type.attribute" />
		
		<xsl:if test="if( not( contains( $type, ':') ) )
			then error( QName( 'E', 'E' ), concat( 'global-templates.xsl : GetAttributeInfo : type must contain a prefix - value = ', $type ) )
			else true()" />
		
		<xsl:variable name="type" select="substring-after( $type, ':' )" />
		
		<xsl:variable name="attribute.type" 
			select="document( $type.schema )/xsd:schema/xsd:complexType
				[@name = $type]/xsd:simpleContent//xsd:attribute
				[@name = $type.attribute]/@type" />
		
		<xsl:choose>
			<!-- 
				If the attribute type is empty and whe have an unqualified datatype then return
				nothing
			-->
			<xsl:when test="not( $attribute.type ) and contains( $global.datatypes.unqualified, $type )" >
				<xsl:value-of select="error( QName( 'E', 'E' ), concat( 'global-templates.xsl : GetAttributeInfo : attribute ', $type.attribute, ' does not excist for ', $type ) )" />
			</xsl:when>
			
			<!-- 
				If the attribute type is empty and whe have an qualified datatype then we have
				to look up the basetype of this datatype and check if the type of the attribute is
				declared there.
			-->
			<xsl:when test="not( $attribute.type ) 
				and not( contains( $global.datatypes.unqualified, $type ) )">
				<xsl:variable name="type.base" 
					select="document( $type.schema )/xsd:schema/xsd:complexType
					[@name = $type]/xsd:simpleContent/xsd:restriction/@base" />
				<xsl:variable name="type.base.schema">
					<xsl:call-template name="GetDataTypeDocument">
						<xsl:with-param name="element.type" select="$type.base"/>
						<xsl:with-param name="element.schema" select="$type.schema"/>
					</xsl:call-template>
				</xsl:variable>
				<xsl:call-template name="GetAttributeInfo">
					<xsl:with-param name="type" select="$type.base"/>
					<xsl:with-param name="type.schema"  select="$type.base.schema"/>
					<xsl:with-param name="type.attribute" select="$type.attribute" />
				</xsl:call-template>
			</xsl:when>
			<xsl:otherwise>
				<xsl:variable name="attribute.type.schema">
					<xsl:call-template name="GetDataTypeDocument">
						<xsl:with-param name="element.type" select="$attribute.type" />
						<xsl:with-param name="element.schema" select="$type.schema" />
					</xsl:call-template>
				</xsl:variable>
				
				<xsl:element name="attribute">
					<xsl:attribute name="name" select="$type.attribute" />
					<xsl:attribute name="type" select="$attribute.type" />
					<xsl:attribute name="type.schema" select="$attribute.type.schema" />
				</xsl:element>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>
	
	<xsl:template name="GetAttributeTypeSchema">
		<xsl:param name="type" />
		<xsl:param name="type.schema" />
		<xsl:param name="type.attribute" />
		
		<xsl:if test="if( not( contains( $type, ':') ) )
			then error( QName( 'E', 'E' ), concat( 'global-templates.xsl : GetAttributeTypeSchema : type must contain a prefix - value = ', $type ) )
			else true()" />
		
		<xsl:variable name="type.attribute.info">
			<xsl:call-template name="GetAttributeInfo">
				<xsl:with-param name="type" select="$type"/>
				<xsl:with-param name="type.schema" select="$type.schema"/>
				<xsl:with-param name="type.attribute" select="$type.attribute"/>
			</xsl:call-template>
		</xsl:variable> 
		
		<xsl:call-template name="GetDataTypeDocument">
			<xsl:with-param name="element.type" select="$type.attribute.info/attribute/@type" />
			<xsl:with-param name="element.schema" select="$type.schema" />
		</xsl:call-template>
	</xsl:template>
	
	<!-- 
		Returns the instance id for the given attribute of a qualified datatype. The result of this
		template is in the following form:
			<instance id="{ID}" src="{SCHEMA}"/>
		If the type is a qualified type which itself doesn't define a type for the attribute the 
		basetype which does define a type for the attribute is looked up. If that basetype is used
		itself in the message the src attribute is ommitted.
	-->
	<xsl:template name="GetInstanceInfoForAttribute">
		<xsl:param name="type" />
		<xsl:param name="type.schema" />
		<xsl:param name="attribute" />
		<xsl:param name="types.used" />
		
		<xsl:if test="if( $types.used )
			then true()
			else error( QName( 'E', 'E' ), 'types.used is not initialized' )" />
		
		<xsl:variable name="attribute.info">
			<xsl:call-template name="GetAttributeInfo">
				<xsl:with-param name="type" select="$type" />
				<xsl:with-param name="type.schema" select="$type.schema" />
				<xsl:with-param name="type.attribute" select="$attribute"/>
			</xsl:call-template>
		</xsl:variable>
		
		<xsl:variable name="type.basetype">
			<xsl:call-template name="GetBaseType">
				<xsl:with-param name="element.type" select="$type" />
				<xsl:with-param name="element.type.schema" select="$type.schema" />
			</xsl:call-template>
		</xsl:variable>
		
		<xsl:variable name="type.basetype.schema">
			<xsl:call-template name="GetDataTypeDocument">
				<xsl:with-param name="element.type" select="$type.basetype" />
				<xsl:with-param name="element.schema" select="$type.schema" />
			</xsl:call-template>
		</xsl:variable>
		
		<xsl:variable name="type.basetype.attribute.info">
			<xsl:call-template name="GetAttributeInfo">
				<xsl:with-param name="type" select="$type.basetype" />
				<xsl:with-param name="type.schema" select="$type.basetype.schema" />
				<xsl:with-param name="type.attribute" select="$attribute" />
			</xsl:call-template>
		</xsl:variable>
		
		<xsl:choose>
			<xsl:when test="$attribute.info
				and $type.basetype.attribute.info">
				<!-- 
					Both type and basetype have an attribute contenttype defined. If the
					attribute contenttype of the type differs from it's basetype then a instance
					must be created for this type.
				-->
				<xsl:choose>
					<xsl:when test="not( $type.basetype.attribute.info/attribute/@type 
						= $attribute.info/attribute/@type )">
						<xsl:element name="instance">
							<xsl:attribute name="id" 
								select="concat( 'instance.codes.', $attribute, '.', $attribute.info/attribute/@type )" />
							<xsl:attribute name="src" select="$attribute.info/attribute/@type.schema"/>
						</xsl:element>
					</xsl:when>
					<xsl:otherwise>
						<!-- 
							Here we have to look up the first basetype which has a type definition for the given
							attribute. If that basetype is in the used types list, only the id for the instance that
							belongs to the attribute of this basetype has to be returned. Otherwise the instance
							has to be created.
							
							NOTE I: This will create two instances when when to types are based on the same
							basetype which itself isn't used in the message. But i won't look further into this to
							get this resolved. Maybe in a later version.
							
							NOTE II: type.basetype-with-attr is of the form:
							<basetype name="{basetype}" schema="{basetype-schema" />
						-->
						<xsl:variable name="type.basetype-with-attr">
							<xsl:call-template name="GetBaseTypeWithAttribute">
								<xsl:with-param name="type" select="$type" />
								<xsl:with-param name="type.attribute" select="$attribute" />
								<xsl:with-param name="type.schema" select="$type.schema" />
							</xsl:call-template>
						</xsl:variable>
						
						<xsl:variable name="type" 
							select="$types.used/types/type[@name = $type.basetype-with-attr/basetype/@name]" />
							
						<xsl:choose>
							<xsl:when test="$type">
								<xsl:element name="instance">
									<xsl:attribute name="id" 
										select="concat( 'instance.codes.'
										, $attribute, '.'
										, substring-after( $type.basetype-with-attr/basetype/@name, ':' ) )" />
								</xsl:element>
							</xsl:when>
							<xsl:otherwise>
								<xsl:element name="instance">
									<xsl:attribute name="id" 
										select="concat( 'instance.codes.'
										, $attribute, '.'
										, substring-after( $type.basetype-with-attr/basetype/@name, ':' ) )" />
									<xsl:attribute name="src" select="$type.basetype-with-attr/basetype/@schema"/>
								</xsl:element>
							</xsl:otherwise>
						</xsl:choose>
					</xsl:otherwise>
				</xsl:choose>
			</xsl:when>
			<xsl:otherwise>
				<xsl:element name="instance">
					<xsl:attribute name="id" >unknown</xsl:attribute>
					<xsl:attribute name="src">unknown</xsl:attribute>
				</xsl:element>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>
	
	<!-- 
		This template looks up the dictionairy entry name for the parent of the element
		with given den.
		
		@param den - the dictionairy entry name of the element for which to look up the parent
		@param element.type - should always be the type of the root element of the current 
			document.
		@param element.schema - the schema where element.type is declared.
	-->
	<xsl:template name="GetParentDen" >
		<xsl:param name="den.search" required="yes" as="xsd:string"/>
		<xsl:param name="element.den" required="yes" as="xsd:string"/>
		<xsl:param name="element.type" required="yes" as="xsd:string"/>
		<xsl:param name="element.schema" required="yes" />
		
		<xsl:variable name="element.children">
			<xsl:call-template name="GetChildElements">
				<xsl:with-param name="parent" select="substring-after( $element.type, ':' )" />
				<xsl:with-param name="parent.schema" select="$element.schema" />
			</xsl:call-template>			
		</xsl:variable>
		
		<xsl:for-each select="$element.children/xsd:element">
			<xsl:variable name="den.current" as="xsd:string"
				select="xsd:annotation/xsd:documentation/ccts:DictionaryEntryName"/>
			
			<xsl:choose>
				<xsl:when test="$den.current = $den.search">
					<xsl:value-of select="$element.den" />					
				</xsl:when>
				<xsl:when test="not( xsd:annotation/xsd:documentation/ccts:Acronym = 'BBIE' )">
					<xsl:variable 
						name="den.parent" select="xsd:annotation/xsd:documentation/ccts:DictionaryEntryName" />
					
					<xsl:variable name="element.child.type.document">
						<xsl:call-template name="GetDataTypeDocument">
							<xsl:with-param name="element.type" select="@type" />
							<xsl:with-param name="element.schema" select="$element.schema"/>
						</xsl:call-template>
					</xsl:variable>
					
					<xsl:call-template name="GetParentDen">
						<xsl:with-param name="den.search" select="$den.search"/>
						<xsl:with-param name="element.den" select="$den.parent" />
						<xsl:with-param name="element.type" select="@type" />
						<xsl:with-param name="element.schema" select="$element.child.type.document" />
					</xsl:call-template>
				</xsl:when>
			</xsl:choose>
		</xsl:for-each>
	</xsl:template>
</xsl:stylesheet>
